
mod driver;
use core::ptr::copy_nonoverlapping;

pub use driver::NetErr;
use driver::NET;
use httparse::{Request, Status};

struct HttpResponse<'b> {
    buf: &'b mut [u8],
    pos: usize,
}

impl <'b> HttpResponse<'b> {
    
    pub fn new<'a: 'b>(buf: &'a mut [u8], content_type: &str) -> Self {
        let mut resp = Self { buf, pos: 0 };
        resp.writeln("HTTP/1.1 200 OK");
        resp.write("Content-Type: ".as_bytes());
        resp.writeln(content_type);
        resp
    }

    fn body(&mut self, body: &[u8]) {
        self.write("Content-Length: ".as_bytes());
        self.write_usize(body.len());
        self.write("\r\n".as_bytes());
        self.write("\r\n".as_bytes());
        self.write(body);
    }

    fn write_usize(&mut self, n: usize) {
        let mut data = [0u8; 10];
        let mut len = 0;
        let mut tmp = n;
        loop {
            tmp = tmp / 10;
            len += 1;
            if tmp == 0 {
                break;
            }
        }
        tmp = n;
        for i in 0..len {
            let x = tmp % 10;
            tmp /= 10;
            data[len - 1 - i] = b'0' + x as u8;
        }
        self.write(&data[..len]);
    }

    fn write(&mut self, s: &[u8]) {
        if (s.len() + self.pos) > self.buf.len() {
            panic!("response buf over");
        }
        let dst = &mut self.buf[self.pos..];
        unsafe { copy_nonoverlapping(s.as_ptr(), dst.as_mut_ptr(), s.len()); }
        self.pos += s.len();
    }

    fn writeln(&mut self, s: &str) {
        self.write(s.as_bytes());
        self.write("\r\n".as_bytes());
    }


}

const HTML: &'static [u8] = include_bytes!("../../index.html");

fn do_handler(buf: &mut [u8]) {
    let mut resp = HttpResponse::new(buf, "text/html");
    resp.body(HTML);
    NET.write(&resp.buf[..resp.pos]).unwrap();
}

pub fn net_run() -> Result<(), NetErr> {
    driver::init()?;

    defmt::println!("net init ok");
    
    let mut buf = [0u8; 1024];
    
    loop {
        NET.wait_read()?;
        let len = NET.read_to_empty(&mut buf)?;
        defmt::println!("recv size:{}", len);

        let mut headers = [httparse::EMPTY_HEADER; 8];
        let mut req = Request::new(&mut headers);
        match req.parse(&buf[..len]) {
            Ok(Status::Complete(position)) => {
                defmt::println!("http parse ok:{}", position);
                do_handler( &mut buf);
            },
            Ok(Status::Partial) => {
                defmt::println!("parse partial");
            },
            Err(_e) => {
                defmt::println!("parse err");
            }
        };
    
    }
}

















